﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using Bowlus.Azure.ServiceManagementWrapper;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace Bowlus.Common
{
    public static class BowlusSettings
    {
        public const string AppHostRoleName = "Bowlus.AppHost";
        public const string FrontEndRoleName = "Bowlus.FrontEnd";

        public const string AppFrontEndSiteName = "AppFrontEnd";
        public const string AppHostEndpointName = "Http";
        public const string AppContainer = "apps";
        public const string TenantCustomizationContainer = "tenantcustomizations";

        // subscription=...;thumbprint=...;servicename=...;deploymentslot=...
        private static string managementString;
        private static object mslockObject = new object();
        public static string ManagementString
        {
            get
            {
                if (managementString == null)
                {
                    lock (mslockObject)
                    {
                        if (managementString == null)
                        {
                            managementString = RoleEnvironment.GetConfigurationSettingValue("ManagementString");
                            // managementString = "subscription=7d402ba0-fd5f-400e-a87f-5dc9e2cc5ce5;thumbprint=95C12CD2A2ACB40E0378DA16EB8EEA5705304765;servicename=danhk2;deploymentslot=Production";

                            // TODO: write a better Regex expression
                            var regx = new System.Text.RegularExpressions.Regex(@"([A-Za-z0-9\-]*)[=;]*");
                            var maches = regx.Matches(managementString);
                            subscription = maches[1].Value.TrimEnd(';');
                            thumbprint = maches[3].Value.TrimEnd(';');
                            servicename = maches[5].Value.TrimEnd(';');
                            deploymentslot = maches[7].Value.TrimEnd(';');
                        }
                    }
                }
                return managementString;
            }
        }

        private static string subscription;
        private static string thumbprint;
        private static string servicename;
        private static string deploymentslot;

        public static string ServiceName
        {
            get
            {
                if (ManagementString == null)
                {
                    // will triger ManagementString initiate
                }
                return servicename;
            }
        }

        public static string DeploymentSlot
        {
            get
            {
                if (ManagementString == null)
                {
                    // will triger ManagementString initiate
                }
                return deploymentslot;
            }
        }

        public static CloudStorageAccount StorageAccount
        {
            get
            {
                return DiagnosticStorageAccount;
            }
        }

        public static CloudStorageAccount DiagnosticStorageAccount
        {
            get
            {
                if(cloudStorageAct == null)
                {
                    cloudStorageAct = CloudStorageAccount.Parse(
                        RoleEnvironment.GetConfigurationSettingValue("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString"));
                }
                return cloudStorageAct;
            }
        }

        public static string TenantHostFromConfigFormat(string tid)
        {
            var formatString = RoleEnvironment.GetConfigurationSettingValue("NewTenantHostFormat");

            return string.Format(formatString, tid);
        }

        private static CloudStorageAccount cloudStorageAct;

        private static IServiceManagementWrapper serviceManagementWrapper = null;

        private static readonly object lockObject = new object();

        public static IServiceManagementWrapper GetManagementService()
        {
            if (ManagementString == null)
            {
                // will triger ManagementString initiate
            }

            var subscriptionId = subscription;
            var managementThumb = thumbprint;

            if (RoleEnvironment.IsEmulated)
                return new ServiceManagementWrapper2();

            if (null == serviceManagementWrapper)
            {
                lock (lockObject)
                {
                    try
                    {
                        Trace.TraceInformation(string.Format("Get Service Management Wrapper for Subscription:{0} Using Certificate Thumbprint:{1}", subscriptionId, managementThumb), "ServiceManagementWrapper", "GetManagementService");

                        var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                        store.Open(OpenFlags.ReadOnly);
                        var certs = store.Certificates.Find(X509FindType.FindByThumbprint, managementThumb, false);
                        if (certs.Count < 1)
                            throw new ApplicationException(string.Format("Cannot Locate Azure Management Certificate by Thumbprint({0}) in LocalMachine Certificate Store", managementThumb));

                        var cert = certs[0];
                        if (!cert.HasPrivateKey)
                            throw new ApplicationException(string.Format("The management cerificate does not have a private key {0}", cert.Thumbprint));

                        serviceManagementWrapper = new ServiceManagementWrapper(subscriptionId, cert);
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError(ex.Message + '\n' + ex.StackTrace);
                    }
                }
            }

            return serviceManagementWrapper;
        }

    }
}
